﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using ST.Buz.Base.Entity;
using ST.Buz.Service;
using ST.Common.Data;
using ST.Common.Util;
using ST.Common.Util.Drawing;
using ST.Common.Util.Model;
using ST.Common.Util.Mvc;
using ST.Common.Util.Text;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;

namespace ST.Buz.Api.Controllers
{
	[Route("sys/attachment")]
	public class Sys_AttachmentController : BaseJsonController
	{
		/// <summary>
		/// 上传文件大小限制
		/// </summary>
		private static int MAX_FILE_SIZE = 10485760;//10M
		private static readonly string[] IMAGE_EXT = new string[] { ".jpg", ".jpeg", ".bmp", ".png", ".gif" };
		private static readonly string[] DOC_EXT = new string[] { ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".wps", ".pdf" };
		private static readonly string[] OTHER_EXT = new string[] { ".7z", ".zip", ".rar" };

		private readonly IServiceSysAttachment service;

		public Sys_AttachmentController(IServiceSysAttachment _service,
			ILogger<Sys_AttachmentController> _logger) : base(_logger)
		{
			service = _service;
		}

		#region 标准接口

		[HttpPost("upload")]
		public ActionResult Upload()
		{
			//Response.Headers.Add("Access-Control-Allow-Origin", "*");

			string callback = Request.Form["callback"];
			try
			{
				string fileType = Request.Form["type"];
				string[] validExtensions = null;
				switch (fileType)
				{
					case "image":
						validExtensions = new string[] { ".jpg", ".jpeg", ".bmp", ".png", ".gif" };
						break;
					case "doc":
						validExtensions = new string[] { ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".wps", ".pdf" };
						break;
					case "file":
						validExtensions = new string[] { ".7z", ".zip", ".rar" };
						break;
					default:
						validExtensions = new string[] { ".jpg", ".jpeg", ".bmp", ".png", ".gif", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".wps", ".pdf", ".7z", ".zip", ".rar" };
						break;
				}
				if (Request.Form.Files == null || Request.Form.Files.Count == 0)
				{
					throw new BuzException("请选择要上传的文件");
				}
				IFormFile file = Request.Form.Files[0];
				if (file.Length == 0)
				{
					throw new BuzException("不能上传空文件");
				}
				string fileExt = Path.GetExtension(file.FileName);
				if (Array.IndexOf(validExtensions, fileExt) < 0)
				{
					throw new BuzException("不支持该文件格式");
				}
				if (file.Length > MAX_FILE_SIZE)
				{
					throw new BuzException("文件大小超出限制（" + MAX_FILE_SIZE + "）");
				}
				UserSession userSession = GetSessionFromRequest();

				string fileName = IDGenerator.NextRand32(userSession.SessionType, userSession.SessionID) + fileExt;
				string fileUrl = "/upload/" + fileName;
				string fileDir = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/upload");
				if (!Directory.Exists(fileDir))
				{
					Directory.CreateDirectory(fileDir);
				}
				string filePath = Path.Combine(fileDir, fileName);
				using (FileStream fs = new FileStream(filePath, FileMode.CreateNew))
				{
					file.CopyTo(fs);
				}

				int tblID = TextHelper.GetInt(Request.Form["tblid"]);
				int infoID = TextHelper.GetInt(Request.Form["infoid"]);
				Sys_Attachment model = new Sys_Attachment
				{
					AddDate = DateTime.Now,
					AddManID = userSession.UserID,
					AddManName = userSession.UserName,
					FileUrl = fileUrl,
					FileName = file.FileName,
					FileSize = (int)file.Length,
					SrcName = file.FileName,
					TableID = tblID,
					InfoID = infoID
				};
				service.Add(model);

				SysAttachmentDetail info = new SysAttachmentDetail
				{
					//info.url = fileUrl;
					url = HttpContextHelper.GetRequestDomainBase(Request) + fileUrl,
					size = (int)file.Length,
					title = file.FileName,
					type = fileType,
					infoid = infoID,
					tblid = tblID
				};
				if (string.IsNullOrEmpty(callback))
				{
					JsonResultBase ret = new JsonResultBase(info)
					{
						StatusCode = (int)HttpStatusCode.Created
					};
					return ret;
				}
				else
				{
					return Content(callback + "(" + Json(info) + ")");
				}
			}
			catch (AuthException ex)
			{
				logger.LogError(ex, "解析请求头部验证信息出错");
				if (string.IsNullOrEmpty(callback))
				{
					return new JsonResultBase(false, ex.Message, (int)HttpStatusCode.Unauthorized);
				}
				else
				{
					ResultData ret = new ResultData(false, ex.Message);
					return Content(callback + "(" + Json(ret) + ")");
				}
			}
			catch (BuzException ex)
			{
				if (string.IsNullOrEmpty(callback))
				{
					return new JsonResultBase(false, ex.Message);
				}
				else
				{
					ResultData ret = new ResultData(false, ex.Message);
					return Content(callback + "(" + Json(ret) + ")");
				}
			}
			catch (Exception ex)
			{
				logger.LogError(ex, "上传文件出错");
				if (string.IsNullOrEmpty(callback))
				{
					return new JsonResultBase(false, "上传失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message), (int)HttpStatusCode.InternalServerError);
				}
				else
				{
					ResultData ret = new ResultData(false, "上传失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
					return Content(callback + "(" + Json(ret) + ")");
				}
			}
		}

		[HttpPost("save")]
		public ActionResult Save()
		{
			try
			{
				if (Request.Form.Files == null || Request.Form.Files.Count == 0)
				{
					throw new BuzException("请选择要上传的文件");
				}
				IFormFile file = Request.Form.Files[0];
				if (file.Length == 0)
				{
					throw new BuzException("不能上传空文件");
				}
				string fileExt = Path.GetExtension(file.FileName);
				if (Array.IndexOf(new string[] { ".jpg", ".jpeg", ".bmp", ".png", ".gif" }, fileExt) < 0)
				{
					throw new BuzException("不支持该文件格式");
				}
				if (file.Length > MAX_FILE_SIZE)
				{
					throw new BuzException("文件大小超出限制（" + MAX_FILE_SIZE + "）");
				}

				UserSession userSession = GetSessionFromRequest();

				string fileName = IDGenerator.NextRand32(userSession.SessionType, userSession.SessionID) + fileExt;
				string fileUrl = "/upload/" + fileName;
				string fileDir = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/upload");
				if (!Directory.Exists(fileDir))
				{
					Directory.CreateDirectory(fileDir);
				}
				string filePath = Path.Combine(fileDir, fileName);
				using (FileStream fs = new FileStream(filePath, FileMode.CreateNew))
				{
					file.CopyTo(fs);
				}

				Sys_Attachment model = new Sys_Attachment
				{
					AddDate = DateTime.Now,
					AddManID = userSession.UserID,
					AddManName = userSession.UserName,
					FileUrl = fileUrl,
					FileName = "",
					FileSize = (int)file.Length,
					SrcName = file.FileName,
					TableID = TextHelper.GetInt(Request.Form["tblid"]),
					InfoID = TextHelper.GetInt(Request.Form["infoid"])
				};
				service.Add(model);

				JsonResultBase ret = new JsonResultBase(model)
				{
					StatusCode = (int)HttpStatusCode.Created
				};
				return ret;
			}
			catch (BuzException ex)
			{
				return new JsonResultBase(false, ex.Message);
			}
			catch (Exception ex)
			{
				logger.LogError(ex, "新增对象信息出错");
				return new JsonResultBase(false, "上传失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message), (int)HttpStatusCode.InternalServerError);
			}
		}

		[ValidateSession]
		[HttpPost("delete")]
		public JsonResult Delete([FromBody] JObject paras)
		{
			try
			{
				CheckParams();

				UserSession sessionCurrent = GetSessionFromRequest();
				var rowID = TextHelper.GetInt(paras, "id");
				var result = service.Delete(rowID, sessionCurrent, false);

				return new JsonResultBase(result);
			}
			catch (AuthException ex)
			{
				return new JsonResultBase(false, ex.Message, (int)HttpStatusCode.Unauthorized);
			}
			catch (BuzException ex)
			{
				return new JsonResultBase(false, ex.Message);
			}
			catch (ArgumentException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				return new JsonResultBase(false, ex.Message, (int)HttpStatusCode.BadRequest);
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				return new JsonResultBase(false, "删除失败", (int)HttpStatusCode.InternalServerError);
			}
		}
		#endregion

		#region 扩展接口
		
		#endregion
	}
}